home *** CD-ROM | disk | FTP | other *** search
Text File | 1994-01-17 | 71.6 KB | 3,785 lines |
- /*C++SIM/
-
-
- Department of Computing Science,
- The University,
- Newcastle upon Tyne,
- UK.
-
- Permission to use, copy, modify and distribute this program for
- evaluation, teaching and/or research purposes only and without fee is
- hereby granted, providing that this copyright and permission notice
- appear on all copies and supporting documentation, and that similar
- conditions are imposed on any individual or organization to whom the
- program is distributed. The University of Newcastle upon Tyne makes no
- representation about the suitability of this software for any purpose.
- It is provided "as is" without express or implied warranty.
-
- $Id: Copyright,v 1.1 1993/06/14 13:07:22 nmcl Exp $
-
-
- tRandom.cc
- TestSet.cc
-
- Process.cc
- * Copyright (C) 1993
- *
- * Department of Computing Science,
- * The University,
- * Newcastle upon Tyne,
- * UK.
- */
-
-
- #ifndef ELEMENT_H_
- #include "Element.h"
- #endif
-
- #ifndef SET_H_
- #include "Set.h"
- #endif
-
-
- Element::Element ()
- : value(0)
- {
- }
-
- Element::Element (long x)
- : value(x)
- {
- }
-
- Element::~Element ()
- {
- }
-
- boolean Element::Belongs (Set* toCheck) const
- {
- boolean found = false;
- Element* temp = (Element*) toCheck->First();
-
- while ((temp) && (!found))
- {
- if (temp->GetValue() == value)
- found = true;
- else
- temp = (Element*) temp->Suc();
- }
-
- return found;
- }
-
-
- #ifdef NO_INLINES
- # define ELEMENT_CC_
- # include "Element.n"
- # undef ELEMENT_CC_
- #endif
- t.
- Process.cc
- Process.cc
- * Copyright (C) 1993
- *
- * Department of Computing Science,
- * The University,
- * Newcastle upon Tyne,
- * UK.
- */
-
-
- /*
- * This is used to simply test the operation of the Head and Link classes.
- */
-
-
- #ifndef ELEMENT_H_
- #define ELEMENT_H_
-
- #ifndef COMMON_H_
- #include "common.h"
- #endif
-
- #ifndef LINK_H_
- #include "Link.h"
- #endif
-
-
- class Set;
-
-
- class Element : public Link
- {
- public:
- Element ();
- Element (long);
- ~Element ();
-
- boolean Belongs (Set*) const;
-
- long GetValue () const;
- void SetValue (long);
-
- private:
- long value;
- };
-
-
- #include "Element.n"
-
- #endif
- $
- TestSet.cc
- Process.cc
- Process.cc
- * Copyright (C) 1993
- *
- * Department of Computing Science,
- * The University,
- * Newcastle upon Tyne,
- * UK.
- */
-
-
- #if defined(NO_INLINES) && !defined(ELEMENT_CC_)
-
- #else
-
- #ifndef NO_INLINES
- # define INLINEF inline
- #else
- # define INLINEF
- #endif
-
- INLINEF long Element::GetValue () const
- {
- return value;
- }
-
- INLINEF void Element::SetValue (long x)
- {
- value = x;
- }
-
-
- #ifdef INLINEF
- # undef INLINEF
- #endif
-
- #endif
-
- * Copyright (C) 1993
- *
- * Department of Computing Science,
- * The University,
- * Newcastle upon Tyne,
- * UK.
- */
-
- #ifndef BREAKS_H_
- #include "Breaks.h"
- #endif
-
- #ifndef MACHINE_H_
- #include "Machine.h"
- #endif
-
- #ifndef QUEUE_H_
- #include "Queue.h"
- #endif
-
- extern Machine* M;
- extern Queue JobQ;
-
- Breaks::Breaks ()
- {
- RepairTime = new UniformStream(1, 10);
- OperativeTime = new UniformStream(20, 1000);
- interrupted_service = false;
- }
-
- Breaks::~Breaks ()
- {
- delete RepairTime;
- delete OperativeTime;
- }
-
- void Breaks::Body ()
- {
- for(;;)
- {
- Hold((*OperativeTime)());
- M->Broken();
- M->Cancel();
-
- if(!JobQ.IsEmpty())
- interrupted_service = true;
-
- Hold((*RepairTime)());
- M->Fixed();
- if (interrupted_service)
- M->ActivateAt(M->ServiceTime() + CurrentTime());
- else
- M->ActivateAt();
-
- interrupted_service = false;
- }
- }
-
- Process.cc
- * Copyright (C) 1993
- *
- * Department of Computing Science,
- * The University,
- * Newcastle upon Tyne,
- * UK.
- */
-
- #ifndef BREAKS_H_
- #define BREAKS_H_
-
- #ifndef RANDOM_H_
- #include <Random.h>
- #endif
-
- #ifndef PROCESS_H_
- #include <Process.h>
- #endif
-
-
- /* Waits for a time interval drawn from the OperativeTime. Then kills of the
- * Machine and waits for a time interval drawn from the RepairTime before
- * restarting the Machine.
- */
-
- class Breaks : public Process
- {
- public:
- Breaks ();
- ~Breaks ();
-
- void Body ();
-
- private:
- UniformStream* RepairTime;
- UniformStream* OperativeTime;
- boolean interrupted_service;
- };
-
- #endif
- errupted_service = true;
-
- Hold((*RepairTime)());
- M->Fixed();
- if (interrupted_service)
- M->ActivateAt(M->ServiceTime() + CurrentTime());
- else
- M->ActivateAt();
-
- interrupted_service = false;
- }
- }
-
- Process.cc
- * Copyright (C) 1993
- *
- * Department of Computing Science,
- * The University,
- * Newcastle upon Tyne,
- * UK.
- */
-
- #include <iostream.h>
-
- #ifndef PROCESS_H_
- #include <Process.h>
- #endif
-
- #ifndef JOB_H_
- #include "Job.h"
- #endif
-
- #ifndef MACHINE_H_
- #include "Machine.h"
- #endif
-
- #ifndef QUEUE_H_
- #include "Queue.h"
- #endif
-
-
- extern Machine* M;
- extern Queue JobQ;
- extern long TotalJobs;
- extern double TotalResponseTime;
- extern Scheduler *sc;
-
- Job::Job ()
- {
- boolean empty;
-
- ResponseTime = 0;
- ArrivalTime = sc->CurrentTime();
- empty = JobQ.IsEmpty();
- JobQ.Enqueue(this);
- TotalJobs++;
-
- if (empty && !M->Processing() && M->IsOperational())
- M->Activate();
- }
-
- Job::~Job ()
- {
- ResponseTime = sc->CurrentTime() - ArrivalTime;
-
- #ifdef DEBUG
- cerr << "ArrivalTime is " << ArrivalTime << "\n";
- cerr << "Time now is " << sc->CurrentTime() << "\n";
- cerr << "ResponseTime is " << ResponseTime << "\n";
- #endif
-
- TotalResponseTime += ResponseTime;
- }
-
- * Copyright (C) 1993
- *
- * Department of Computing Science,
- * The University,
- * Newcastle upon Tyne,
- * UK.
- */
-
- #ifndef JOB_H_
- #define JOB_H_
-
- /* Instances of this class represent the jobs which the Machine attempts
- * to process.
- * If the -DDEBUG option is added to the CFLAGS for the Makefile then useful
- * debugging code will be produced.
- */
-
- class Job
- {
- public:
- Job ();
- ~Job ();
-
- private:
- double ArrivalTime;
- double ResponseTime;
- };
-
- #endif
- ;
-
- ResponseTime = 0;
- ArrivalTime C++SIM/Examples/Machine.cc
- * Copyright (C) 1993
- *
- * Department of Computing Science,
- * The University,
- * Newcastle upon Tyne,
- * UK.
- */
-
- #ifndef MACHINE_H_
- #include "Machine.h"
- #endif
-
- #ifndef JOB_H_
- #include "Job.h"
- #endif
-
- #ifndef QUEUE_H_
- #include "Queue.h"
- #endif
-
-
- extern long ProcessedJobs;
- extern long JobsInQueue;
- extern long CheckFreq;
- extern double MachineActiveTime;
- extern Queue JobQ;
-
- Machine::Machine (double mean)
- {
- STime = new ExponentialStream(mean);
- operational = true;
- working = false;
- }
-
- Machine::~Machine () { delete STime; }
-
- void Machine::Body ()
- {
- double ActiveStart, ActiveEnd;
-
- for (;;)
- {
- working = true;
-
- while (!JobQ.IsEmpty())
- {
- ActiveStart = CurrentTime();
- CheckFreq++;
-
- JobsInQueue += JobQ.QueueSize();
- Job* J = JobQ.Dequeue();
- Hold((*STime)());
-
- ActiveEnd = CurrentTime();
- MachineActiveTime += ActiveEnd - ActiveStart;
- ProcessedJobs++;
- delete J;
- }
-
- working = false;
- Cancel();
- set_evtime(CurrentTime());
- }
- }
-
- boolean Machine::Processing () { return working; }
-
- void Machine::Broken () { operational = false; }
-
- void Machine::Fixed ()
- {
- operational = true;
- set_evtime(CurrentTime());
- }
-
- boolean Machine::IsOperational () { return operational; }
-
- double Machine::ServiceTime () { return (*STime)(); }
-
- * Copyright (C) 1993
- *
- * Department of Computing Science,
- * The University,
- * Newcastle upon Tyne,
- * UK.
- */
-
- #ifndef MACHINE_H_
- #define MACHINE_H_
-
- #ifndef RANDOM_H_
- #include <Random.h>
- #endif
-
- #ifndef PROCESS_H_
- #include <Process.h>
- #endif
-
-
- /* This is the machine which services job requests. It is prone to simulated
- * failures caused by the Breaks process.
- */
-
- class Machine : public Process
- {
- public:
- Machine (double);
- ~Machine ();
-
- void Body ();
-
- void Broken ();
- void Fixed ();
- boolean IsOperational ();
- boolean Processing ();
- double ServiceTime ();
-
- private:
- ExponentialStream* STime;
- boolean operational;
- boolean working;
- };
-
- #endif
- ();
- CheckFreq++;
-
- JobsInQueue += JobQ.QueueSize();
- Job* J = JobQ.Dequeue();
- Hold((*STime)());
-
- ActiveEnd = CurrentTime();
- MachineActiveTime += ActiveEnd - ActiveStart;
- ProcessedJobs++;
- delete J;
- }
-
- working = false;
- Cancel();
- set_evtime(CurrentTime());
- }
- }
-
- boolean Machine::ProceC++SIM/Examples/MachineShop.cc
- * Copyright (C) 1993
- *
- * Department of Computing Science,
- * The University,
- * Newcastle upon Tyne,
- * UK.
- */
-
- #include <iostream.h>
-
- #ifndef PROCESS_H_
- #include <Process.h>
- #endif
-
- #ifndef MACHINESHOP_H_
- #include "MachineShop.h"
- #endif
-
- #ifndef ARRIVALS_H_
- #include "Arrivals.h"
- #endif
-
- #ifndef MACHINE_H_
- #include "Machine.h"
- #endif
-
- #ifndef JOB_H_
- #include "Job.h"
- #endif
-
- #ifndef QUEUE_H_
- #include "Queue.h"
- #endif
-
- #ifndef BREAKS_H_
- #include "Breaks.h"
- #endif
-
-
- Scheduler* sc;
- Machine* M;
- Queue JobQ;
- long TotalJobs = 0;
- long ProcessedJobs = 0;
- long JobsInQueue = 0;
- long CheckFreq = 0;
- double TotalResponseTime = 0;
- double MachineActiveTime = 0;
-
- MachineShop::MachineShop () {}
-
- MachineShop::~MachineShop () {}
-
- void MachineShop::Body ()
- {
- sc = new Scheduler();
- Arrivals* A = new Arrivals(10);
- M = new Machine(8);
- Job* J = new Job;
-
- #ifdef BREAKS
- Breaks* B = new Breaks;
- B->Activate();
- #endif
-
- A->Activate();
- sc->Resume();
-
- while (ProcessedJobs < 100000)
- Hold(10000);
-
- cerr << "Total number of jobs processed " << TotalJobs << "\n";
- cerr << "Total response time of " << TotalResponseTime << "\n";
-
- cerr << "Average response time = " << (TotalResponseTime / ProcessedJobs) << "\n";
- cerr << "Probability that machine is busy = " << (MachineActiveTime / CurrentTime()) << "\n";
- cerr << "Average number of jobs present = " << (JobsInQueue / CheckFreq) << "\n";
- sc->Suspend();
- A->Suspend();
-
- #ifdef BREAKS
- B->Suspend();
- #endif
- }
-
- void MachineShop::Await ()
- {
- Resume();
- Thread::Self()->Suspend();
- }
-
- * Copyright (C) 1993
- *
- * Department of Computing Science,
- * The University,
- * Newcastle upon Tyne,
- * UK.
- */
-
- #ifndef MACHINESHOP_H_
- #define MACHINESHOP_H_
-
- #ifndef PROCESS_H_
- #include <Process.h>
- #endif
-
-
- /* This class starts up all of the main processes involved in the simulation.
- * If the -DBREAKS option is added to the CFLAGS for the Makefile then the
- * Breaks process will be created to deactivate of the Machine process at
- * suitable intervals. Otherwise it will not be created and the Machine will
- * operate uninterrupted.
- */
-
- class MachineShop : public Process
- {
- public:
- MachineShop ();
- ~MachineShop ();
-
- void Body ();
- void Await ();
- };
-
- #endif
- () {}
-
- MachineShop::~MachineShop () {}
-
- void MachineShop::Body ()
- {
- sc = new Scheduler();
- Arrivals* A = new Arrivals(10);
- M = new Machine(8);
- Job* J = new Job;
-
- #ifdef BREAKS
- Breaks* B = new Breaks;
- B->Activate();
- #endif
-
- A->Activate();
- sc->Resume();
-
- while (ProcessedJobs < 100000)
- Hold(10000);
-
- C++SIM/Examples/Main.cc
- * Copyright (C) 1993
- *
- * Department of Computing Science,
- * The University,
- * Newcastle upon Tyne,
- * UK.
- */
-
- #include <iostream.h>
-
- #ifndef COMMON_H_
- #include <common.h>
- #endif
-
- #ifndef PROCESS_H_
- #include <Process.h>
- #endif
-
- #ifndef MACHINESHOP_H_
- #include "MachineShop.h"
- #endif
-
-
- int main()
- {
- Thread_Type::Initialize(); // Initialize the threads package.
-
- MachineShop m; // Start up the real main body of the simulation.
- m.Await(); // Suspend main's thread (NOTE: this MUST be done by all applications.)
-
- return 0;
- }
- */
-
- class MachineShop : public Process
- {
- public:
- MachineShop ();
- ~MachineShop ();
-
- void Body ();
- void Await ();
- };
-
- #endif
- () {}
-
- MachineShop::~MachineShop () {}
-
- void MachineShop::Body ()
- {
- sc = new Scheduler();
- Arrivals* A = new Arrivals(10);
- M = new Machine(8);
- Job* J = new Job;
-
- #ifdef BREAKS
- Breaks* B = new Breaks;
- B->Activate();
- #endif
-
- A->Activate();
- sc->Resume();
-
- while (ProcessedJobs < 100000)
- Hold(10000);
-
- C++SIM/Examples/Queue.cc
- * Copyright (C) 1993
- *
- * Department of Computing Science,
- * The University,
- * Newcastle upon Tyne,
- * UK.
- */
-
- #ifndef QUEUE_H_
- #include "Queue.h"
- #endif
-
- Queue::Queue ()
- {
- head = 0;
- length = 0;
- }
-
- Queue::~Queue () { delete head; }
-
- boolean Queue::IsEmpty ()
- {
- if (head == 0)
- return true;
- else
- return false;
- }
-
- long Queue::QueueSize () { return length; }
-
- Job* Queue::Dequeue ()
- {
- if (IsEmpty())
- return 0;
-
- List* ptr = head;
- head = head->next;
-
- length--;
- return ptr->work;
- }
-
- void Queue::Enqueue (Job* toadd)
- {
- List* ptr = head;
-
- if (IsEmpty())
- {
- head = new List;
- ptr = head;
- }
- else
- {
- while (ptr->next != 0)
- ptr = ptr->next;
-
- ptr->next = new List;
- ptr = ptr->next;
- }
-
- ptr->next = 0;
- ptr->work = toadd;
- length++;
- }
-
-
- M = new Machine(8);
- Job* J = new Job;
-
- #ifdef BREAKS
- Breaks* B = new Breaks;
- B->Activate();
- #endif
-
- A->Activate();
- sc->Resume();
-
- while (ProcessedJobs < 100000)
- Hold(10000);
-
- C++SIM/Examples/Queue.h
- * Copyright (C) 1993
- *
- * Department of Computing Science,
- * The University,
- * Newcastle upon Tyne,
- * UK.
- */
-
- #ifndef QUEUE_H_
- #define QUEUE_H_
-
- #ifndef PROCESS_H_
- #include <Process.h>
- #endif
-
- #ifndef JOB_H_
- #include "Job.h"
- #endif
-
-
- /* This is the queue on which Jobs are placed before they are used. */
-
- struct List
- {
- Job* work;
- List* next;
- };
-
- class Queue
- {
- public:
- Queue ();
- ~Queue ();
-
- boolean IsEmpty ();
- long QueueSize ();
- Job *Dequeue ();
- void Enqueue (Job*);
-
- private:
- List* head;
- long length;
- };
-
- #endif
- ist* ptr = head;
-
- if (IsEmpty())
- {
- head = new List;
- ptr = head;
- }
- else
- {
- while (ptr->next != 0)
- ptr = ptr->next;
-
- ptr->next = new List;
- ptr = ptr->next;
- }
-
- ptr->next = 0;
- ptr->work = toadd;
- length++;
- }
-
-
- M = new Machine(8);
- Job* J = new Job;
-
- #ifdef BREAKS
- Breaks* B = new Breaks;
- B->Activate();
- #endif
-
- A->Activate();
- sc->Resume();
-
- while (ProcessedJobs < 100000)
- Hold(10000);
-
- C++SIM/Examples/README
- * Copyright (C) 1993
- *
- * Department of Computing Science,
- * The University,
- * Newcastle upon Tyne,
- * UK.
- */
-
- This director contains an example of a simulation written using the simulation
- package. The example is taken from the book by Isi Mitrani (Simulation
- Techniques for Discrete Event Systems p22).
-
- The simulation is of a service which attempts to execute as many requests for
- jobs as possible. The job requests are queued until the service can deal with
- them. However, the service is prone to failures, and so jobs started will be
- delayed until the service has been reactivated.
-
- The classes provided include:
-
- Arrivals - This class controls the rate at which Jobs arrive at
- the service (Machine)
-
- Breaks - This class controls the availability of the Machine by
- "killing" it and restarting it at intervals drawn from
- a Uniform distribution.
-
- Job - This class represents the jobs which the Machine must process.
-
- Machine - This is the Machine on which the service resides. It obtains
- jobs from the job queue for the service and then attempts to
- execute them. The machine can fail and so the response time for
- jobs is not guaranteed to be the same.
-
- MachineShop - This is the main part of the simulation which starts the
- various processes (Scheduler, Arrivals, Machine, Job)
- involved. It also prints out statistics for the response time
- for the jobs.
-
- Queue - This represents the queue which Jobs are placed on prior to being
- used by the Machine (service).
-
- Main - This is the body of the program which initializes the threads package
- prior to the simulation starting.
-
- * Copyright (C) 1993
- *
- * Department of Computing Science,
- * The University,
- * Newcastle upon Tyne,
- * UK.
- */
-
- #ifndef ARRIVALS_H_
- #define ARRIVALS_H_
-
- #ifndef PROCESS_H_
- #include <Process.h>
- #endif
-
- #ifndef RANDOM_H_
- #include <Random.h>
- #endif
-
-
- /* Controls the rate at which Jobs arrive at the Machine */
-
- class Arrivals : public Process
- {
- public:
- Arrivals (double);
- ~Arrivals ();
-
- void Body ();
-
- private:
- ExponentialStream* InterArrivalTime;
- };
-
- #endif
- ver, the service is prone to faiC++SIM/Examples/Arrivals.cc
- * Copyright (C) 1993
- *
- * Department of Computing Science,
- * The University,
- * Newcastle upon Tyne,
- * UK.
- */
-
- #include <iostream.h>
-
- #ifndef ARRIVALS_H_
- #include "Arrivals.h"
- #endif
-
- #ifndef JOB_H_
- #include "Job.h"
- #endif
-
- Arrivals::Arrivals (double mean) { InterArrivalTime = new ExponentialStream(mean); }
-
- Arrivals::~Arrivals () { delete InterArrivalTime; }
-
- void Arrivals::Body ()
- {
- for(;;)
- {
- Hold((*InterArrivalTime)());
- Job* work = new Job();
- }
- }
- dif
- ver, the service is prone to faiC++SIM/Examples/Makefile
-
- CC = cc
- C++ = CC3.0.1
- CPP = /lib/cpp
- LEX = lex
-
- MDEP = /usr/local/Arjuna/bin/makedepend
- STRIPDEPEND = /usr/local/Arjuna/bin/stripdepend
-
- CFLAGS = -g
- CPPFLAGS =
- C++FLAGS = -g +w
- LDFLAGS = -g
- LEXFLAGS =
-
- MDEPFLAGS =
-
- LOCAL_CFLAGS =
- LOCAL_CPPFLAGS = -I/usr/local/Arjuna/include -I.. -I.
-
- LOCAL_C++FLAGS =
- LOCAL_LDFLAGS = -L../ -lThreads \
- -L/usr/lib -lm -llwp
-
- LOCAL_MDEPFLAGS = -I/usr/local/include/CC
-
- OBJECTS = Arrivals.o Breaks.o Job.o Queue.o Machine.o Main.o MachineShop.o
-
- SOURCES = Arrivals.cc Breaks.cc Job.cc Queue.cc Machine.cc Main.cc MachineShop.cc
-
- HEADERS = Arrivals.h Breaks.h Job.h Queue.h Machine.h MachineShop.h
-
- all: Main
-
- Main: $(OBJECTS) $(HEADERS) ../libThreads.a
- $(C++) -o Main $(OBJECTS) $(LDFLAGS) $(LOCAL_LDFLAGS)
-
- Main.o: Main.cc
- $(C++) -c $(CPPFLAGS) $(LOCAL_CPPFLAGS) $(C++FLAGS) $(LOCAL_C++FLAGS) Main.cc
-
- MachineShop.o: MachineShop.cc
- $(C++) -c $(CPPFLAGS) $(LOCAL_CPPFLAGS) $(C++FLAGS) $(LOCAL_C++FLAGS) MachineShop.cc
-
- Arrivals.o: Arrivals.cc
- $(C++) -c $(CPPFLAGS) $(LOCAL_CPPFLAGS) $(C++FLAGS) $(LOCAL_C++FLAGS) Arrivals.cc
-
- Breaks.o: Breaks.cc
- $(C++) -c $(CPPFLAGS) $(LOCAL_CPPFLAGS) $(C++FLAGS) $(LOCAL_C++FLAGS) Breaks.cc
-
- Job.o: Job.cc Job.h
- $(C++) -c $(CPPFLAGS) $(LOCAL_CPPFLAGS) $(C++FLAGS) $(LOCAL_C++FLAGS) Job.cc
-
- Queue.o: Queue.cc Queue.h
- $(C++) -c $(CPPFLAGS) $(LOCAL_CPPFLAGS) $(C++FLAGS) $(LOCAL_C++FLAGS) Queue.cc
-
- Machine.o: Machine.cc Machine.h
- $(C++) -c $(CPPFLAGS) $(LOCAL_CPPFLAGS) $(C++FLAGS) $(LOCAL_C++FLAGS) Machine.cc
-
- clean:
- rm -f *.o
-
- vclean: clean
- rm -f Main *~* *.bak
-
- depend:
- $(MDEP) $(CPPFLAGS) $(LOCAL_CPPFLAGS) $(MDEPFLAGS) $(LOCAL_MDEPFLAGS) $(SOURCES)
-
- # DO NOT DELETE THIS LINE -- make depend depends on it.
-
- * Copyright (C) 1993
- *
- * Department of Computing Science,
- * The University,
- * Newcastle upon Tyne,
- * UK.
- */
-
-
- /*
- * This class essentially defines the linked list manager used by the SIMSET
- * class in SIMULA.
- */
-
-
- #ifndef HEAD_H_
- #include "Head.h"
- #endif
-
- #ifndef LINK_H_
- #include "Link.h"
- #endif
-
- #include <iostream.h>
-
-
- Head::Head ()
- : first(0),
- last(0)
- {
- }
-
- Head::~Head () { Clear(); }
-
- void Head::AddFirst (Link* element)
- {
- if (!element)
- return;
-
- if (!first)
- {
- if (element->inList)
- element->Out();
-
- first = element;
- last = element;
- element->inList = true;
- }
- else
- {
- first->Precede(element);
- first = first->Pred();
- }
- }
-
- void Head::AddLast (Link* element)
- {
- if (last)
- {
- element->Follow(last);
- last = element;
- }
- else
- {
- if (element->inList)
- element->Out();
-
- element->inList = true;
- first = element;
- last = element;
- }
- }
-
- long Head::Cardinal () const
- {
- long numberOfElements = 0;
- Link *tempPtr = first;
-
- while (tempPtr)
- {
- numberOfElements++;
- tempPtr = tempPtr->Suc();
- }
-
- return numberOfElements;
- }
-
- void Head::Clear ()
- {
- Link *tempPtr = first, *marker = 0;
-
- while (!tempPtr)
- {
- marker = tempPtr;
- tempPtr = tempPtr->Suc();
- delete marker;
- }
- }
-
-
- #ifdef NO_INLINES
- # define HEAD_CC_
- # include "Head.n"
- # undef HEAD_CC_
- #endif
-
- hineShop.cc
- $(C++) -c $(CPPFLAGS) $(LOCAL_CPPFLAGS) $(C++FLAGS) $(LOCAL_C++FLAGS) MachineShop.cc
-
- Arrivals.o: Arrivals.cc
- $(C++) -c $(CPPFLAGS) $C++SIM/Head.h
- * Copyright (C) 1993
- *
- * Department of Computing Science,
- * The University,
- * Newcastle upon Tyne,
- * UK.
- */
-
-
- /*
- * This class essentially defines the linked list manager used by the SIMSET
- * class in SIMULA.
- */
-
-
- #ifndef HEAD_H_
- #define HEAD_H_
-
- #ifndef COMMON_H_
- #include "common.h"
- #endif
-
-
- class Link;
-
-
- class Head
- {
- public:
- Head ();
- virtual ~Head ();
-
- Link* First () const;
- Link* Last () const;
-
- void AddFirst (Link*);
- void AddLast (Link*);
-
- long Cardinal () const;
- boolean Empty () const;
-
- void Clear ();
-
- private:
- Link *first, *last;
- };
-
-
- #include "Head.n"
-
- #endif
- gnu_thread.h
- Process.cc
- # include "Head.n"
- # undef HEAD_CC_
- #endif
-
- hineShop.cc
- $(C++) -c $(CPPFLAGS) $(LOCAL_CPPFLAGS) $(C++FLAGS) $(LOCAL_C++FLAGS) MachineShop.cc
-
- Arrivals.o: Arrivals.cc
- $(C++) -c $(CPPFLAGS) $C++SIM/Head.n
- * Copyright (C) 1993
- *
- * Department of Computing Science,
- * The University,
- * Newcastle upon Tyne,
- * UK.
- */
-
-
- #if defined(NO_INLINES) && !defined(HEAD_CC_)
-
- #else
-
- #ifndef NO_INLINES
- # define INLINEF inline
- #else
- # define INLINEF
- #endif
-
- INLINEF Link* Head::First () const
- {
- return first;
- }
-
- INLINEF Link* Head::Last () const
- {
- return last;
- }
-
- INLINEF boolean Head::Empty () const
- {
- return (boolean) (Cardinal() == 0);
- }
-
- #ifdef INLINEF
- # undef INLINEF
- #endif
-
- #endif
-
- t.h
- * Copyright (C) 1993
- *
- * Department of Computing Science,
- * The University,
- * Newcastle upon Tyne,
- * UK.
- */
-
- To create the thread library libThreads.a simply type make. If you do not
- possess Sun's lwp package then you will have to create a new class along the
- same lines as the lwp_thread class and link it into the library. Such a class
- has been provided for the GNU threads package, which is also included.
-
- * Copyright (C) 1993
- *
- * Department of Computing Science,
- * The University,
- * Newcastle upon Tyne,
- * UK.
- */
-
-
- /*
- * This class defines the elements of the linked lists within SIMSET.
- */
-
-
- #ifndef LINK_H_
- #include "Link.h"
- #endif
-
- #ifndef HEAD_H_
- #include "Head.h"
- #endif
-
-
- Link::Link ()
- : prev(0),
- next(0),
- inList(false)
- {
- }
-
- Link::~Link () { RemoveElement(); }
-
- void Link::RemoveElement ()
- {
- if (prev)
- prev->next = next;
-
- if (next)
- next->prev = prev;
-
- inList = false;
- }
-
- Link* Link::Out ()
- {
- RemoveElement();
- return this;
- }
-
- void Link::InTo (Head* list)
- {
- if (list)
- {
- list->AddLast(this);
- return;
- }
-
- (void) Out();
- }
-
- void Link::Precede (Link* element)
- {
- if (!element)
- (void) Out();
- else
- if (!element->inList)
- (void) Out();
- else
- {
- if (inList)
- (void) Out();
-
- element->addBefore(this);
- }
- }
-
- void Link::Follow (Link* element)
- {
- if (!element)
- (void) Out();
- else
- if (!element->inList)
- (void) Out();
- else
- {
- if (inList)
- (void) Out();
-
- element->addAfter(this);
- }
- }
-
- void Link::addAfter (Link* toAdd)
- {
- toAdd->inList = true;
- toAdd->prev = this;
-
- if (!next)
- next = toAdd;
- else
- {
- next->prev = toAdd;
- toAdd->next = next;
- next = toAdd;
- }
- }
-
- void Link::addBefore (Link* toAdd)
- {
- toAdd->inList = true;
- toAdd->next = this;
-
- if (!prev)
- prev = toAdd;
- else
- {
- prev->next = toAdd;
- toAdd->prev = prev;
- prev = toAdd;
- }
- }
-
- void Link::Follow (Head* list)
- {
- if (list)
- list->AddFirst(this);
- }
-
-
- #ifdef NO_INLINES
- # define LINK_CC_
- # include "Link.n"
- # undef LINK_CC_
- #endif
- DELETE THIS LINE -- make depend depends on it.
-
- * Copyright (C) 1993
- *
- * Department of Computing Science,
- * The University,
- * Newcastle upon Tyne,
- * UK.
- */
-
-
- /*
- * This class defines the elements of the linked lists within SIMSET.
- */
-
-
- #ifndef LINK_H_
- #define LINK_H_
-
- #ifndef COMMON_H_
- #include "common.h"
- #endif
-
-
- class Head;
-
-
- class Link
- {
- public:
- virtual ~Link ();
-
- Link* Suc () const;
- Link* Pred () const;
-
- Link* Out ();
- void InTo (Head*);
-
- void Precede (Link*);
- void Precede (Head*);
- void Follow (Link*);
- void Follow (Head*);
-
- boolean inList;
-
- protected:
- Link (); // can only derive from this class
-
- private:
- void RemoveElement ();
-
- void addAfter (Link*);
- void addBefore (Link*);
-
- Link *prev, *next;
- };
-
-
- #include "Link.n"
-
- #endif
- #endif
-
-
- class Head;
-
-
- class Link
- {
- public:
- virtual ~Link ();
-
- Link* Suc () const;
- Link* Pred () const;
-
- Link* Out ();
- void InTo (Head*);
-
- void Precede (Link*);
- void Precede (Head*);
- void Follow (Link*);
- C++SIM/Link.n
- * Copyright (C) 1993
- *
- * Department of Computing Science,
- * The University,
- * Newcastle upon Tyne,
- * UK.
- */
-
-
- #if defined(NO_INLINES) && !defined(LINK_CC_)
-
- #else
-
- #ifndef NO_INLINES
- # define INLINEF inline
- #else
- # define INLINEF
- #endif
-
- INLINEF Link* Link::Pred () const
- {
- return prev;
- }
-
- INLINEF Link* Link::Suc () const
- {
- return next;
- }
-
- INLINEF void Link::Precede (Head* list)
- {
- this->InTo(list);
- }
-
- #ifdef INLINEF
- # undef INLINEF
- #endif
-
- #endif
- Makefile
- * Copyright (C) 1993
- *
- * Department of Computing Science,
- * The University,
- * Newcastle upon Tyne,
- * UK.
- */
-
- /*
- * Various useful definitions.
- */
-
-
- #ifndef COMMON_H_
- #define COMMON_H_
-
- #include <iostream.h>
-
- // Do not forget to change the Makefile accordingly for the right thread library!
-
- // Can choose from LWP_Thread or GNU_Thread
-
- #define Thread_Type LWP_Thread
-
- // Can choose from LWPTHREAD or GNUTHREAD
-
- #define LWPTHREAD
-
- #ifndef true
- typedef int boolean;
- #define true 1
- #define false 0
- #endif
-
- #endif
-
- Process.cc
- (void) Out();
- else
- if (!element->inList)
- (void) Out();
- else
- {
- if (inList)
- (void) Out();
-
- element->addBefore(this);
- }
- }
-
- void Link::Follow (Link* element)
- {
- if (!element)
- (void) Out();
- else
- if (!element->inList)
- (void) Out();C++SIM/Process.h
- * Copyright (C) 1993
- *
- * Department of Computing Science,
- * The University,
- * Newcastle upon Tyne,
- * UK.
- */
-
- #ifndef PROCESS_H_
- #define PROCESS_H_
-
- #ifndef COMMON_H_
- #include "common.h"
- #endif
-
- #ifdef GNUTHREAD
- # ifndef GNU_THREAD_H_
- # include "gnu_thread.h"
- # endif
- #else
- # ifndef LWP_THREAD_H_
- # include "lwp_thread.h"
- # endif
- #endif
-
-
- /* This is the main class for the simulation package. All objects which are to possess
- * independent threads of control but which are to be controlled by the simulation
- * scheduler MUST be derived from the Process class. The Scheduler, which is also an
- * object which possesses an independent thread and which exists within the simulation
- * environment, is shown here, but is only derived from the Thread_Type class and not Process
- * as it is the central controller for the simulation environment and as such runs independently
- * of everything else.
- * If debugging is turned on (-DDEBUG added to the CFLAGS for the Makefile) then the scheduler
- * will print out the current simulation time and other information.
- *
- * Thread_Type is a means of "transparently" changing the thread base class implementation
- * from (at present) lwp_thread to gnu_thread. This should be changed in the file common.h
- * and the Makefile may need changing to include the right thread library.
- */
-
- static double SimulatedTime = 0.0;
-
-
- class Scheduler : public Thread_Type
- {
- public:
- Scheduler ();
- ~Scheduler ();
-
- void Body ();
- double CurrentTime () const;
-
- private:
- double ReActivateTime;
- Thread* mainthread;
- };
-
- class Process : public Thread_Type
- {
- public:
- static const int Never;
-
- virtual ~Process ();
-
- double Time () const; // returns the simulated time at which the current process is active
- static double CurrentTime (); // returns the current simulation time
-
- // There are four ways to activate a process:
- // 1) before another process,
- // 2) after another process,
- // 3) at a specified (simulated) time, or
- // 4) after a specified (simulated) delay
-
- void Activate ();
- void ActivateBefore (Process &);
- void ActivateAfter (Process &);
- void ActivateAt (double AtTime = SimulatedTime, boolean prior = false);
- void ActivateDelay (double AtTime = SimulatedTime, boolean prior = false);
-
- // Similarly, there are four ways to reactivate
- // Note that if a process is already scheduled, the reactivate
- // will simply re-schedule the process.
-
- void ReActivateBefore (Process &);
- void ReActivateAfter (Process &);
- void ReActivateAt (double AtTime = SimulatedTime, boolean prior = false);
- void ReActivateDelay (double AtTime = SimulatedTime, boolean prior = false);
- void ReActivate ();
-
-
- void Cancel (); // cancels next burst of activity, process becomes idle
- double evtime () const; // time at which process is scheduled to be active
- void set_evtime (double); // set wakeuptime (used by Scheduler)
-
- boolean idle (); // true if process is not currently scheduled to wake up
- boolean terminated () const; // returns whether or not the object has been passivated
-
- // The pure virtual function, Body, defines the code that executes in the process
- virtual void Body () = 0;
-
- protected:
- Process ();
- void Hold (double t);// suspend current process for simulated time t
- void Passivate (); // suspend current process (i.e., make idle)
-
- private:
- double wakeuptime;
- boolean Terminated;
- };
-
-
- #include "Process.n"
-
- #endif // PROCESS_H
-
- * Copyright (C) 1993
- *
- * Department of Computing Science,
- * The University,
- * Newcastle upon Tyne,
- * UK.
- */
-
- #ifndef PROCESSCONS_H_
- #include "ProcessCons.h"
- #endif
-
-
- ProcessCons::ProcessCons (Process &p, ProcessCons *n) { Proc = &p; Next = n; }
-
-
- #ifdef NO_INLINES
- # define PROCESSCONS_CC_
- # include "ProcessCons.n"
- # undef PROCESSCONS_CC_
- #endif
- Random.cc
- TestSet.cc
- * Copyright (C) 1993
- *
- * Department of Computing Science,
- * The University,
- * Newcastle upon Tyne,
- * UK.
- */
-
- #ifndef PROCESSCONS_H_
- #define PROCESSCONS_H_
-
- #ifndef COMMON_H_
- #include "common.h"
- #endif
-
- #ifndef PROCESS_H_
- #include "Process.h"
- #endif
-
-
- class ProcessCons
- {
- public:
- ProcessCons (Process &p, ProcessCons *n);
- Process *car ();
- ProcessCons *cdr ();
- void SetfCdr (ProcessCons *n);
-
- private:
- Process *Proc;
- ProcessCons *Next;
- };
-
-
- #include "ProcessCons.n"
-
- #endif
- <MC++SIM/ProcessCons.n
- * Copyright (C) 1993
- *
- * Department of Computing Science,
- * The University,
- * Newcastle upon Tyne,
- * UK.
- */
-
-
- #if defined(NO_INLINES) && !defined(PROCESSCONS_CC_)
-
- #else
-
- #ifndef NO_INLINES
- # define INLINEF inline
- #else
- # define INLINEF
- #endif
-
- INLINEF Process *ProcessCons::car ()
- {
- return Proc;
- }
-
- INLINEF ProcessCons *ProcessCons::cdr ()
- {
- return Next;
- }
-
- INLINEF void ProcessCons::SetfCdr (ProcessCons *n)
- {
- Next = n;
- }
-
-
- #ifdef INLINEF
- # undef INLINEF
- #endif
-
- #endif
-
- * Copyright (C) 1993
- *
- * Department of Computing Science,
- * The University,
- * Newcastle upon Tyne,
- * UK.
- */
-
- #ifndef PROCESSITERATOR_H_
- #include "ProcessIterator.h"
- #endif
-
-
- ProcessIterator::ProcessIterator (ProcessList &L) { ptr = L.Head; }
-
- Process *ProcessIterator::operator ()()
- {
- if (ptr)
- {
- ProcessCons *p = ptr;
- ptr = ptr->cdr();
- return p->car();
- }
-
- return 0;
- }
-
- * Copyright (C) 1993
- *
- * Department of Computing Science,
- * The University,
- * Newcastle upon Tyne,
- * UK.
- */
-
- #ifndef PROCESSITERATOR_H_
- #define PROCESSITERATOR_H_
-
- #ifndef COMMON_H_
- #include "common.h"
- #endif
-
- #ifndef PROCESS_H_
- #include "Process.h"
- #endif
-
- #ifndef PROCESSLIST_H_
- #include "ProcessList.h"
- #endif
-
- #ifndef PROCESSCONS_H_
- #include "ProcessCons.h"
- #endif
-
-
- class ProcessIterator
- {
- public:
- ProcessIterator (class ProcessList &L);
- Process *operator ()();
-
- private:
- ProcessCons *ptr;
- };
-
- #endif
- ion
- * environment, is shown here, but is only derived from the Thread_Type class and not Process
- * as it is the central controller for the simulation environment and as such runs independently
- * of everything else.
- * If debugging is turned on (-DDEBUG added to the CFLAGS for the Makefile) then the scheduler
- * will print oC++SIM/README
- * Copyright (C) 1993
- *
- * Department of Computing Science,
- * The University,
- * Newcastle upon Tyne,
- * UK.
- */
-
- D. McCue, M. Little Computing Laboratory
- 29 November 1991 University of Newcastle upon Tyne, NE1 7RU, England
-
- This is version 1.0 of C++SIM, a set of c++ class definitions that mimic the
- process-based simulation facilities of SIMULA and the SIMSET routines.
-
- The co-routine facility of Simula is implemented by Sun threads.
- Classes are provided for various random number distributions.
-
- The following classes are defined:
-
- Process - An abstract class that exports the major functions
- of the Simula class, process. To use, derive your own
- class from the class Process. The pure virtual function,
- Body, is the "main" procedure of the class. Note that,
- like Simula, a process is not scheduled to run when it is
- created. It must be explicitly 'activated'.
-
- ProcessList - A list class for processes that (by default) orders
- the elements by event time.
-
- ProcessIterator - An iterator class for ProcessList.
-
- ProcessCons - Allows LISP-like list manipulation (car & cdr).
-
- Random - A series of classes which provide various random number
- streams.
-
- Element & Head - These classes form the basis of the SIMSET utility.
-
- thread - The basic thread class, which defines what operations other
- threads packages must provide. This is essentially a template
- which allows other thread packages to be used as long as they
- provide at least the operations necessary for this class.
-
- lwp_thread - This is the Sun threads class.
-
- gnu_thread - This is the interface to Gnu's thread package.
-
-
-
- If you find any bugs or make modifications (e.g., ports to other thread
- packages) or port the package to other systems then please let me know
- so I can keep the sources up-to-date for other users.
-
- Note: if you are interested in using C++SIM with Gnu threads then get in
- touch with me and I will let you know how to go about that.
-
- Send to: M.C.Little@ac.uk.newcastle
-
-
-
- er a specified (simulated) delay
-
- void Activate ();
- void ActivateBefore (Process &);
- void ActivateAfter (Process &);
- void ActivateAt (double AtTime = SimulatedTime, boolean prior = false);
- void ActivateDelay (double AtTime = SimulatedTime, boolean prior = false);
-
- // Similarly, there are four ways to reactivate
- // Note that if a process is already scheduled, the reactivate
- // will simply re-schedule the process.
-
- void ReActivateBefore (Process &);
- void ReActiC++SIM/ProcessList.cc
- * Copyright (C) 1993
- *
- * Department of Computing Science,
- * The University,
- * Newcastle upon Tyne,
- * UK.
- */
-
- #ifndef PROCESSLIST_H_
- #include "ProcessList.h"
- #endif
-
-
- ProcessList::ProcessList () { Head = 0; }
-
- void ProcessList::Insert (Process &p, boolean prior)
- {
- // If list is empty, insert at head
- if (!Head)
- {
- Head = new ProcessCons(p, Head);
- return;
- }
-
- // Try to insert before (if there is anything scheduled later)
- ProcessIterator iter(*this);
-
- for (Process *prev = 0, *q = iter(); q; prev = q, q = iter())
- {
- if (prior)
- {
- if (q->evtime() >= p.evtime())
- {
- (void) InsertBefore(p, *q);
- return;
- }
- }
- else
- if (q->evtime() > p.evtime())
- {
- (void) InsertBefore(p, *q);
- return;
- }
- }
-
- // Got to insert at the end (currently pointed at by 'prev'
- (void) InsertAfter(p, *prev);
- }
-
- boolean ProcessList::InsertBefore (Process &ToInsert, Process &Before)
- {
- for (ProcessCons *prev=0, *p=Head; p; prev=p, p=p->cdr())
- if (p->car() == &Before) {
- ProcessCons *newcons = new ProcessCons(ToInsert, p);
- if (prev)
- prev->SetfCdr(newcons);
- else
- Head = newcons;
-
- return true;
- }
- return false;
- }
-
- boolean ProcessList::InsertAfter (Process &ToInsert, Process &After)
- {
- for (ProcessCons *p = Head; p; p = p->cdr())
- if (p->car() == &After) {
- ProcessCons *newcons = new ProcessCons(ToInsert, p->cdr());
- p->SetfCdr(newcons);
- return true;
- }
- return false;
- }
-
- Process *ProcessList::Remove (const Process *element)
- {
- Process *p = 0;
-
- // Take care of boundary condition - empty list
- if (!Head) return 0;
-
- // Change unspecified element to "remove head of list" request
- if (element == 0)
- return(Remove(Head->car()));
-
- for (ProcessCons *prev = 0, *ptr = Head; ptr; prev = ptr, ptr = ptr->cdr())
- {
- if (ptr->car() == element)
- {
- ProcessCons *oldcons = ptr;
- // unlink the cons cell for the element we're removing
- if (prev)
- prev->SetfCdr(ptr->cdr());
- else
- Head = ptr->cdr();
- // return the pointer to the process
- p = ptr->car();
- // flush the dead cons cell
- delete oldcons;
- }
- }
-
- return p;
- }
- oid ActivateAt (double AtTime = SimulatedTime, boolean prior = false);
- void ActivateDelay (double AtTime = SimulatedTime, boolean prior = false);
-
- // Similarly, there are four ways to reactivate
- // Note that if a process is already scheduled, the reactivate
- // will simply re-schedule the process.
-
- void ReActivateBefore (Process &);
- void ReActiC++SIM/Random.cc
- * Copyright (C) 1993
- *
- * Department of Computing Science,
- * The University,
- * Newcastle upon Tyne,
- * UK.
- */
-
- #include <iostream.h>
- #include <math.h>
-
- #ifndef RANDOM_H_
- #include "Random.h"
- #endif
-
-
- RandomStream::RandomStream (long MGSeed, long LCGSeed)
- {
- // Clean up input parameters
- if ((MGSeed&1) == 0) MGSeed--;
- if (MGSeed<0) MGSeed = -MGSeed;
- if (LCGSeed<0) LCGSeed = -LCGSeed;
-
- // Initialise state
- MSeed = MGSeed;
- LSeed = LCGSeed;
-
- for (int i=0; i< (sizeof(series)/sizeof(double)); i++)
- series[i] = MGen();
- }
-
- double RandomStream::MGen ()
- {
- // A multiplicative generator, courtesy I. Mitrani 1992,
- // private correspondence
- // Y[i+1] = Y[i] * 5^5 mod 2^26
- // period is 2^24, initial seed must be odd
-
- const long int two2the26th = 67108864; // 2**26
-
- MSeed = (MSeed * 25) % two2the26th;
- MSeed = (MSeed * 25) % two2the26th;
- MSeed = (MSeed * 5) % two2the26th;
-
- return (double) MSeed / (double) two2the26th;
- }
-
- double RandomStream::Uniform ()
- {
- // A linear congruential generator based on the algorithm from
- // "Algorithms", R. Sedgewick, Addison-Wesley, Reading MA, 1983.
- // pp. 36-38.
- const long m=100000000;
- const long b=31415821;
- const long m1=10000;
-
- // Do the multiplication in pieces to avoid overflow
- long p0 = LSeed%m1,
- p1 = LSeed/m1,
- q0 = b%m1,
- q1 = b/m1;
-
- LSeed = (((((p0*q1+p1*q0)%m1)*m1+p0*q0)%m) + 1) % m;
-
- // The results of the LC generator are shuffled with
- // the multiplicative generator as suggested by
- // Maclaren and Marsaglia (See Knuth Vol2, Seminumerical Algorithms)
-
- long choose = LSeed % (sizeof(series)/sizeof(double));
-
- double result = series[choose];
- series[choose] = MGen();
-
- return result;
- }
-
- double RandomStream::Error ()
- {
- const long r=100;
- const long N=100*r;
- long i, f[r];
- for (i=0; i<r; i++) f[i]=0;
- for (i=0; i<N; i++) f[(int) (Uniform()*r)]++;
- long t=0;
- for (i=0; i<r; i++) t += f[i]*f[i];
- double rt = (double) r*t;
- double rtN = rt / (double) N - (double) N;
- return 1.0 - (rtN / r);
- }
-
- UniformStream::UniformStream (double l, double h, int StreamSelect)
- {
- lo = l;
- hi = h;
- range = hi-lo;
- for (int ss=0; ss<StreamSelect*1000; ss++) (void) Uniform();
- }
-
- double UniformStream::operator() ()
- {
- return lo+(range*Uniform());
- }
-
- Draw::Draw(double p, int StreamSelect) : s(0,1)
- {
- prob = p;
- for (int ss=0; ss<StreamSelect*1000; ss++) (void) s();
- }
-
- boolean Draw::operator() ()
- {
- double x = s();
-
- if (x >= prob)
- return true;
- else
- return false;
- }
-
- ExponentialStream::ExponentialStream (double m, int StreamSelect)
- {
- Mean = m;
- for (int ss=0; ss<StreamSelect*1000; ss++) (void) Uniform();
- }
-
- double ExponentialStream::operator() ()
- {
- return -Mean*log(Uniform());
- }
-
- ErlangStream::ErlangStream (double m, double s, int StreamSelect)
- {
- Mean = m;
- StandardDeviation = s;
-
- double z = Mean/StandardDeviation;
- k = (long) (z*z);
- for (int ss=0; ss<StreamSelect*1000; ss++) (void) Uniform();
- }
-
- double ErlangStream::operator() ()
- {
- double z=1.0;
- for (int i=0; i<k; i++) z*=Uniform();
- return -(Mean/k)*log(z);
- }
-
- HyperExponentialStream::HyperExponentialStream (double m, double s, int StreamSelect)
- {
- Mean = m;
- StandardDeviation = s;
- double cv,z;
- cv=StandardDeviation/Mean;
- z = cv*cv;
- p = 0.5*(1.0-sqrt((z-1.0)/(z+1.0)));
- for (int ss=0; ss<StreamSelect*1000; ss++) (void) Uniform();
- }
-
- double HyperExponentialStream::operator() ()
- {
- double z = (Uniform()>p) ? Mean/(1.0-p) : Mean/p;
- return -0.5*z*log(Uniform());
- }
-
- NormalStream::NormalStream (double m, double s, int StreamSelect)
- {
- Mean = m;
- StandardDeviation = s;
- z = 0.0;
- for (int ss=0; ss<StreamSelect*1000; ss++) (void) Uniform();
- }
-
- double NormalStream::operator() ()
- {
- // Use the polar method, due to Box, Muller and Marsaglia
- // Taken from Seminumerical Algorithms, Knuth, Addison-Wesley, p.117
-
- double X2;
-
- if (z!=0.0) {
- X2 = z;
- z = 0.0;
- } else {
- double S, v1, v2;
- do {
- v1 = 2.0*Uniform()-1.0;
- v2 = 2.0*Uniform()-1.0;
- S = v1*v1 + v2*v2;
- } while (S>=1.0);
-
- S = sqrt((-2.0*log(S))/S);
- X2 = v1*S;
- z = v2*S;
- }
-
- return Mean + X2*StandardDeviation;
- }
-
- * Copyright (C) 1993
- *
- * Department of Computing Science,
- * The University,
- * Newcastle upon Tyne,
- * UK.
- */
-
- #ifndef PROCESSLIST_H_
- #define PROCESSLIST_H_
-
- #ifndef COMMON_H_
- #include "common.h"
- #endif
-
- #ifndef PROCESS_H_
- #include "Process.h"
- #endif
-
- #ifndef PROCESSITERATOR_H_
- #include "ProcessIterator.h"
- #endif
-
- #ifndef PROCESSCONS_H_
- #include "ProcessCons.h"
- #endif
-
-
- class ProcessList
- {
- public:
- ProcessList ();
- void Insert (Process &, boolean prior=false);
- boolean InsertBefore (Process &ToInsert, Process &Before);
- boolean InsertAfter (Process &ToInsert, Process &After);
- Process *Remove (const Process *p=0);
-
- private:
- friend class ProcessIterator;
- ProcessCons *Head;
- };
-
- #endif
- eriod is 2^24, initial seed must be odd
-
- const long int two2the26th = 67108864; // 2**26
-
- MSeed = (MSeed * 25) % two2the26th;
- MSeed = (MSeed * 25) % two2the26th;
- MSeed = (MSeed * 5) % two2the26th;
-
- return (double) MSeed / (double) two2the26th;
- }
-
- double RandomStream::Uniform ()
- {C++SIM/Set.cc
- * Copyright (C) 1993
- *
- * Department of Computing Science,
- * The University,
- * Newcastle upon Tyne,
- * UK.
- */
-
- #ifndef SET_H_
- #include "Set.h"
- #endif
-
- #ifndef ELEMENT_H_
- #include "Element.h"
- #endif
-
- #include <iostream.h>
-
-
- Set::Set () {}
-
- Set::~Set () {}
-
- Set* Set::Intersect (Set* toCheck) const
- {
- Set* tempSet = new Set;
- Element *E = 0;
-
- if (!Empty() && !toCheck->Empty())
- {
- E = (Element*) First();
-
- while (E)
- {
- if (E->Belongs(toCheck))
- {
- Element* toAdd = new Element(E->GetValue());
- toAdd->InTo(tempSet);
- }
-
- E = (Element*) E->Suc();
- }
- }
-
- return tempSet;
- }
- Process *p=0);
-
- private:
- friend class ProcessIterator;
- ProcessCons *Head;
- };
-
- #endif
- eriod is 2^24, initial seed must be odd
-
- const long int two2the26th = 67108864; // 2**26
-
- MSeed = (MSeed * 25) % two2the26th;
- MSeed = (MSeed * 25) % two2the26th;
- MSeed = (MSeed * 5) % two2the26th;
-
- return (double) MSeed / (double) two2the26th;
- }
-
- double RandomStream::Uniform ()
- {C++SIM/Random.h
- * Copyright (C) 1993
- *
- * Department of Computing Science,
- * The University,
- * Newcastle upon Tyne,
- * UK.
- */
-
- #ifndef RANDOM_H_
- #define RANDOM_H_
-
- #ifndef COMMON_H_
- #include "common.h"
- #endif
-
-
- ////////////////////////////////////////////////////////////////////////////////
- // //
- // This file contains the interfaces for five different (pseudo-) random //
- // number generators: //
- // //
- // 1) Uniform - returns a number drawn from a uniform distribution //
- // with the given lower and upper bounds. //
- // Note: there are two versions of this class, one //
- // returning integers and the other doubles //
- // //
- // 2) Exponential - returns a number from an exponential distribution //
- // with the given mean //
- // //
- // 3) Erlang - returns a number from an Erlang distribution with //
- // the given mean and standard deviation //
- // //
- // 4) HyperExponential - returns a number from a hyperexpontial distribution //
- // with the given mean and standard deviation //
- // //
- // 5) Normal - returns a number from a normal distribution with //
- // the given mean and standard deviation. //
- // //
- ////////////////////////////////////////////////////////////////////////////////
-
-
- ////////////////////////////////////////////////////////////////////////////////
- // The class RandomStream is an abstract base class from which the other //
- // distribution classes are derived. //
- ////////////////////////////////////////////////////////////////////////////////
- class RandomStream
- {
- public:
- RandomStream (long MGSeed=772531L, long LCGSeed=1878892440L);
- virtual double operator() ()=0;
- double Error (); // returns a chi-square error measure on the uniform
- // distribution function
- protected:
- double Uniform ();
-
- private:
- double MGen ();
- double series[128];
- long MSeed, LSeed;
- };
-
- class UniformStream : public RandomStream
- {
- public:
- UniformStream (double lo, double hi, int StreamSelect=0);
- virtual double operator() ();
-
- private:
- double lo,hi;
- double range;
- };
-
- class Draw
- {
- public:
- Draw (double p, int StreamSelect=0);
- virtual boolean operator() ();
- private:
- UniformStream s;
- double prob;
- };
-
- class ExponentialStream : public RandomStream
- {
- public:
- ExponentialStream (double Mean, int StreamSelect=0);
- virtual double operator() ();
-
- private:
- double Mean;
- };
-
- class ErlangStream : public RandomStream
- {
- public:
- ErlangStream (double Mean, double StandardDeviation, int StreamSelect=0);
- virtual double operator() ();
-
- private:
- double Mean,StandardDeviation;
- long k;
- };
-
- class HyperExponentialStream : public RandomStream
- {
- public:
- HyperExponentialStream (double Mean, double StandardDeviation, int StreamSelect=0);
- virtual double operator() ();
-
- private:
- double Mean,StandardDeviation;
- double p;
- };
-
- class NormalStream : public RandomStream
- {
- public:
- NormalStream (double Mean, double StandardDeviation, int StreamSelect=0);
- virtual double operator() ();
-
- private:
- double Mean,StandardDeviation;
- double z;
- };
-
- #endif // RANDOM_H
-
- lgorithms, Knuth, Addison-Wesley, p.117
-
- double X2;
-
- if (z!=0.0) {
- X2 = z;
- z = 0.0;
- } else {
- double SC++SIM/Set.h
- * Copyright (C) 1993
- *
- * Department of Computing Science,
- * The University,
- * Newcastle upon Tyne,
- * UK.
- */
-
- /*
- * This is used to simply test the operation of the Head and Link classes.
- */
-
- #ifndef SET_H_
- #define SET_H_
-
- #ifndef COMMON_H_
- #include "common.h"
- #endif
-
- #ifndef HEAD_H_
- #include "Head.h"
- #endif
-
- #ifndef LINK_H_
- #include "Link.h"
- #endif
-
-
- class Set : public Head
- {
- public:
- Set ();
- ~Set ();
-
- Set* Intersect (Set*) const;
- };
-
- #endif
- C++SIM/TestRandom.cc
- * Copyright (C) 1993
- *
- * Department of Computing Science,
- * The University,
- * Newcastle upon Tyne,
- * UK.
- */
-
- #include <stdlib.h> // to get getopt
- #include <iostream.h>
- #include "Random.h"
-
- void Gen(int count, RandomStream *r, const char *title)
- {
- // Create and initialise buckets for a bar graph
- int i;
- int bucket[100];
- for (i=0; i<100; i++) bucket[i]=0;
-
- // generate numbers and update bucket counts
- for (i=0; i<count; i++) {
- double result = (*r)();
- int idx = result < 0.0 ? 0 : (result > 100.0) ? 100 : (int) result;
- bucket[idx]++;
- }
-
- // output a title followed by the bucket counts
- cout << endl << '"' << title << '"' << endl;
- for (i=0; i<100; i++)
- cout << i << ".0 " << bucket[i] << endl;
-
- cerr << "Chi-Square error measure: " << r->Error() << endl;
- }
-
- int main (int argc, char **argv)
- {
- extern char *optarg;
- extern int optind;
- int c;
- int count=10000;
- int errflg = 0;
- int uniform=0, normal=0, exponential=0, hyperexponential=0, erlang=0;
- int skip=0;
-
- while ((c = getopt(argc, argv, "s:c:unxhe")) != -1)
- switch(c) {
- case 'c': count = atoi(optarg); break;
- case 'u': uniform++; break;
- case 'n': normal++; break;
- case 'x': exponential++; break;
- case 'h': hyperexponential++; break;
- case 'e': erlang++; break;
- case 's': skip = atoi(optarg); break;
-
- case '?':
- default: errflg++;
- }
-
- // ASSERT: argc-optind == number of arguments remaining
- // argv[optind] == first non-flag argument
-
- if (errflg || (argc-optind)) {
- cerr << "usage: " << argv[0] << "[-c <number>][-u][-n][-x][-h][-e]" << endl;
-
- cerr << "\t-c 99\t\tgenerate 99 points for each distribution" << endl;
- cerr << "\t-u\t\toutput a data set for a uniform distribution" << endl;
- cerr << "\t-n\t\toutput a data set for a normal distribution" << endl;
- cerr << "\t-x\t\toutput a data set for an exponential distribution" << endl;
- cerr << "\t-h\t\toutput a data set for a hyperexponential distribution" << endl;
- cerr << "\t-e\t\toutput a data set for an erlang distribution" << endl;
- return 2;
- }
-
- // output a normal distribution by default
- if (!uniform && !normal && !exponential && !hyperexponential && !erlang)
- normal++;
-
- cout << "TitleText: Random Number Distributions"
- << " (" << count << " numbers/distribution)"
- << endl;
-
- for (int q=0; q<skip; q++) delete new UniformStream(0.0, 100.0);
-
- if (uniform) Gen (count, new UniformStream (0.0, 100.0), "Uniform");
- if (normal) Gen (count, new NormalStream (50.0, 15.0), "Normal");
- if (exponential) Gen (count, new ExponentialStream(50.0), "Exponential");
- if (hyperexponential) Gen (count, new HyperExponentialStream(50.0, 55.0), "HyperExponential");
- if (erlang) Gen (count, new ErlangStream(50.0, 15.0), "Erlang");
-
- return 0;
- }
- };
-
- class Draw
- {
- public:
- Draw (double p, int StreamSelect=0);
- virtual boolean operator() ();
- private:
- UniformStream s;
- douC++SIM/TestSet.cc
- * Copyright (C) 1993
- *
- * Department of Computing Science,
- * The University,
- * Newcastle upon Tyne,
- * UK.
- */
-
- #ifndef SET_H_
- #include "Set.h"
- #endif
-
- #ifndef ELEMENT_H_
- #include "Element.h"
- #endif
-
- #include <iostream.h>
-
-
- int main ()
- {
- Set S1, S2;
- Set *S3 = 0;
- Element* E = 0;
-
- for (int i = 0; i < 10; i++)
- {
- E = new Element(i);
- E->InTo(&S1);
- }
-
- for (int j = 8; j < 14; j++)
- {
- E = new Element(j);
- E->InTo(&S2);
- }
-
- S3 = S1.Intersect(&S2);
-
- E = (Element*) S3->First();
-
- cout << "Intersection is:" << endl;
- while (E)
- {
- cout << "value: " << E->GetValue() << endl;
- E = (Element*) E->Suc();
- }
-
- return 0;
- }
- i++)
- cout << i << ".0 " << bucket[i] << endl;
-
- cerr << "Chi-Square error measure: " << r->Error() << endl;
- }
-
- int main (int argc, char **argv)
- {
- extern char *optarg;
- extern int optind;
- int c;
- int count=10000;
- int errflg = 0;
- int uniform=0, normal=0, exponential=0, hyperexponential=0, erlang=0;
- C++SIM/Makefile
-
- CC = cc
- C++ = CC3.0.1
- CPP = /lib/cpp
- LEX = lex
-
- MDEP = /usr/local/Arjuna/bin/makedepend
- STRIPDEPEND = /usr/local/Arjuna/bin/stripdepend
-
- CFLAGS = -g
- CPPFLAGS =
- C++FLAGS = -g +w
- LDFLAGS = -g
- LEXFLAGS =
-
- MDEPFLAGS =
-
- LOCAL_CFLAGS =
- LOCAL_CPPFLAGS =
-
- LOCAL_C++FLAGS =
- LOCAL_LDFLAGS = -L/usr/lib -lm -llwp
-
- LOCAL_MDEPFLAGS = -I/usr/local/include/CC
-
- LIB = libThreads.a
-
- OBJECTS = Process.o ProcessIterator.o ProcessList.o ProcessCons.o \
- Link.o Head.o Set.o Element.o \
- thread.o lwp_thread.o Random.o
-
- SOURCES = Process.cc ProcessIterator.cc ProcessList.cc ProcessCons.cc \
- Link.cc Head.cc Set.cc Element.cc \
- thread.cc lwp_thread.cc Random.cc
-
- HEADERS = ProcessCons.h ProcessIterator.h ProcessList.h common.h \
- Link.h Head.h Set.h Element.h \
- thread.h lwp_thread.h Random.h
-
- INLINES = Element.n Head.n Link.n Process.n ProcessCons.n
-
- all: $(LIB)
-
- Process.o: Process.cc Process.h Process.n
- $(C++) -c $(CPPFLAGS) $(LOCAL_CPPFLAGS) $(C++FLAGS) $(LOCAL_C++FLAGS) Process.cc
-
- ProcessCons.o: ProcessCons.cc ProcessCons.h ProcessCons.n
- $(C++) -c $(CPPFLAGS) $(LOCAL_CPPFLAGS) $(C++FLAGS) $(LOCAL_C++FLAGS) ProcessCons.cc
-
- ProcessIterator.o: ProcessIterator.cc ProcessIterator.h
- $(C++) -c $(CPPFLAGS) $(LOCAL_CPPFLAGS) $(C++FLAGS) $(LOCAL_C++FLAGS) ProcessIterator.cc
-
- ProcessList.o: ProcessList.cc ProcessList.h
- $(C++) -c $(CPPFLAGS) $(LOCAL_CPPFLAGS) $(C++FLAGS) $(LOCAL_C++FLAGS) ProcessList.cc
-
- Link.o: Link.cc Link.h Link.n
- $(C++) -c $(CPPFLAGS) $(LOCAL_CPPFLAGS) $(C++FLAGS) $(LOCAL_C++FLAGS) Link.cc
-
- Head.o: Head.cc Head.h Head.n
- $(C++) -c $(CPPFLAGS) $(LOCAL_CPPFLAGS) $(C++FLAGS) $(LOCAL_C++FLAGS) Head.cc
-
- Set.o: Set.cc Set.h
- $(C++) -c $(CPPFLAGS) $(LOCAL_CPPFLAGS) $(C++FLAGS) $(LOCAL_C++FLAGS) Set.cc
-
- Element.o: Element.cc Element.h Element.n
- $(C++) -c $(CPPFLAGS) $(LOCAL_CPPFLAGS) $(C++FLAGS) $(LOCAL_C++FLAGS) Element.cc
-
- Random.o: Random.cc Random.h
- $(C++) -c $(CPPFLAGS) $(LOCAL_CPPFLAGS) $(C++FLAGS) $(LOCAL_C++FLAGS) Random.cc
-
- thread.o: thread.cc thread.h
- $(C++) -c $(CPPFLAGS) $(LOCAL_CPPFLAGS) $(C++FLAGS) $(LOCAL_C++FLAGS) thread.cc
-
- lwp_thread.o: lwp_thread.cc lwp_thread.h
- $(C++) -c $(CPPFLAGS) $(LOCAL_CPPFLAGS) $(C++FLAGS) $(LOCAL_C++FLAGS) lwp_thread.cc
-
- gnu_thread.o: gnu_thread.cc gnu_thread.h
- $(C++) -c $(CPPFLAGS) $(LOCAL_CPPFLAGS) $(C++FLAGS) $(LOCAL_C++FLAGS) gnu_thread.cc
-
- TestRandom: TestRandom.o $(OBJECTS) $(HEADERS) $(INLINES)
- $(C++) -o TestRandom TestRandom.o $(LIB) $(LDFLAGS) $(LOCAL_LDFLAGS)
-
- TestRandom.o: TestRandom.cc
- $(C++) -c $(CPPFLAGS) $(LOCAL_CPPFLAGS) $(C++FLAGS) $(LOCAL_C++FLAGS) TestRandom.cc
-
- TestSet: TestSet.o $(OBJECTS) $(HEADERS) $(INLINES)
- $(C++) -o TestSet TestSet.o $(LIB) $(LDFLAGS) $(LOCAL_LDFLAGS)
-
- TestSet.o: TestSet.cc
- $(C++) -c $(CPPFLAGS) $(LOCAL_CPPFLAGS) $(C++FLAGS) $(LOCAL_C++FLAGS) TestSet.cc
-
- $(LIB) : $(OBJECTS)
- ar rv $@ $?
- ranlib $(LIB)
-
- clean:
- rm -f *.o
-
- vclean: clean
- rm -f *~* libThreads.a TestRandom TestSet
- .a
-
- OBJECTS = Process.o ProcessIterator.o ProcessList.o ProcessCons.o \
- Link.o Head.o Set.o Element.o \
- thread.o lwp_thrC++SIM/gnu_thread.cc
- * Copyright (C) 1993
- *
- * Department of Computing Science,
- * The University,
- * Newcastle upon Tyne,
- * UK.
- */
-
- #include <iostream.h>
- #include <sys/types.h>
-
- #define _INIT_
- #include <gnulwp.h>
-
- #ifndef GNUTHREAD_H_
- #include "gnu_thread.h"
- #endif
-
-
- long GNU_Thread::base_key = 0;
- boolean GNU_Thread::DoWait = true;
- boolean GNU_Thread::SuspendMain = false;
- int GNU_Thread::count = 0;
- const int GNU_Thread::MaxPriority = 7;
-
-
- GNU_Thread::GNU_Thread (int prio)
- {
- to_wait = 0;
- caddr_t p1;
-
- initlp(MaxPriority);
- p1 = (caddr_t) this;
- thread_key = base_key++;
- my_block = creatp(prio, GNU_Thread::Execute, 8000, 0, 0, p1);
- }
-
- GNU_Thread::~GNU_Thread () {}
-
- void GNU_Thread::Execute (int dummy1, char** dummy2, GNU_Thread* p1)
- {
- // Do this to remove compiler warnings.
- dummy1 = 0;
- dummy2 = 0;
-
- if ((p1->thread_key == 1) && (Self()->Current_Thread() == 0))
- {
- signals(p1->to_wait);
- p1->Body();
- }
- else
- {
- p1->to_wait = creats(0);
- p1->Suspend();
- p1->Body();
- }
- }
-
- void GNU_Thread::Suspend ()
- {
- if ((thread_key == 0) && (Self()->Current_Thread() == 0) && (count < 2))
- count++;
-
- if ((count == 2) && (!SuspendMain))
- {
- SuspendMain = true;
- struct sem* p = creats(0);
- waits(p);
- }
-
- if ((thread_key == 1) && (Self()->Current_Thread() == 0))
- {
- if (DoWait)
- {
- DoWait = false;
- waits(to_wait);
- }
- }
- else
- waits(to_wait);
- }
-
- void GNU_Thread::Resume ()
- {
- if ((thread_key == 1) && (Self()->Current_Thread() == 0))
- {
- readyp(my_block);
- to_wait = creats(0);
- Suspend();
- }
- else
- signals(to_wait);
- }
-
- long GNU_Thread::Current_Thread () const { return thread_key; }
-
- void GNU_Thread::Initialize () { initlp(1); }
- AGS) $(LOCAL_C++FLAGS) Set.cc
-
- Element.o: Element.cc Element.h Element.n
- $(C++) -c $(CPPFLAGS) $(LOCAL_CPPFLAGS) $(C++FLAGS) $(LOCAL_C++FLAGS) Element.cc
-
- Random.o: Random.cc Random.h
- $(C++) -c $(CPPFLAGS) $(LOCAL_CPPFLAGS) $(C++FLAGS) $(LOCAL_C++FLAGS) Random.cc
-
- thread.o: thread.cc thread.h
- $(C++) -c $(CPPFLAGS) $(LOCALC++SIM/gnu_thread.h
- * Copyright (C) 1993
- *
- * Department of Computing Science,
- * The University,
- * Newcastle upon Tyne,
- * UK.
- */
-
- #ifndef GNU_THREAD_H_
- #define GNU_THREAD_H_
-
- #ifndef COMMON_H_
- #include "common.h"
- #endif
-
- #ifndef THREAD_H_
- #include "thread.h"
- #endif
-
-
- #define MINPRIO 2
-
-
- class GNU_Thread : public Thread
- {
- public:
- virtual void Suspend (); // Suspend an active thread
- virtual void Resume (); // Resume a suspended thread
-
- virtual void Body () = 0; // Body of "active" object (defined in the deriving class)
- virtual long Current_Thread () const; // Returns current thread id
-
- // Initialize must be called exactly once at the start of the program
- static void Initialize ();
-
- protected:
- static const int MaxPriority; // Maximum priority of a thread
- static long base_key;
-
- GNU_Thread (int priority = MaxPriority); // Create thread with given (or maximum) priority
- virtual ~GNU_Thread ();
-
- private:
- static void Execute (int, char**, GNU_Thread*); // This routine calls the 'main' object code
- static boolean DoWait;
- static boolean SuspendMain;
- static int count;
-
- long thread_key;
- struct sem* to_wait;
- struct pcb* my_block;
- };
-
- #endif
- }
-
- if ((thread_key == 1) && (Self()->Current_Thread() == 0))
- {
- if (DoWait)
- {
- DoWait = false;
- waits(to_wait);
- }
- }
- else
- waits(to_wait);
- }
-
- void GNU_Thread::Resume ()
- {
- if ((thread_key == 1) && (Self()->Current_Thread() == 0))
- {
- readyp(my_block);
- C++SIM/lwp_thread.cc
- * Copyright (C) 1993
- *
- * Department of Computing Science,
- * The University,
- * Newcastle upon Tyne,
- * UK.
- */
-
- #ifndef COMMON_H_
- #include "common.h"
- #endif
-
- #ifndef LWPTHREAD_H_
- #include "lwp_thread.h"
- #endif
-
-
- /* These are the Sun C routines which give access to threads. They have to be
- * defined in this way. The multiple definitions for lwp_create are as a result
- * of the way in which C++ allows C routines to be declared and the way in which
- * Sun's lwp_create is defined.
- */
-
- extern "C"
- {
- #include <lwp/stackdep.h>
-
- int pod_setmaxpri(int);
- int lwp_setstkcache(int, int);
- #ifndef Scheduler_
- #ifdef Main_
- int lwp_create(thread_t*, void (*func)(), int, int, stkalign_t*, int);
- #else
- int lwp_create(thread_t*, void (*func)(LWP_Thread *), int, int, stkalign_t*, int, caddr_t);
- #endif
- #endif
- int lwp_yield(thread_t);
- int lwp_suspend(thread_t);
- int lwp_resume(thread_t);
- int lwp_setpri(thread_t, int);
- int lwp_self(thread_t*);
- int lwp_ping(thread_t);
- int lwp_sleep(struct timeval);
- }
-
- //
- // Class LWP_Thread
- //
-
-
- const int LWP_Thread::MaxPriority=10;
-
- #ifdef __GNUG__
- thread_t* LWP_Thread::firstThread = 0;
- boolean LWP_Thread::done = false;
- #endif
-
-
- LWP_Thread::LWP_Thread (int prio)
- {
- caddr_t p1;
-
- p1 = (caddr_t) this;
- (void) lwp_create(&mid, LWP_Thread::Execute, prio, 0, lwp_newstk(), 1, p1);
- thread_key = mid.thread_key;
- (void) lwp_suspend(mid);
- }
-
- // For creating the LWP_Thread for "main"
-
- LWP_Thread::LWP_Thread (thread_t tid)
- {
- thread_key = tid.thread_key;
- }
-
- LWP_Thread::~LWP_Thread () {}
-
- long LWP_Thread::Current_Thread () const
- {
- thread_t tid;
-
- (void) lwp_self(&tid);
-
- return tid.thread_key;
- }
-
- void LWP_Thread::Execute (LWP_Thread *p1)
- {
- #ifdef __GNUG__
- if ((LWP_Thread::firstThread == 0) && (!done))
- {
- LWP_Thread::firstThread = new thread_t;
- (void) lwp_self(LWP_Thread::firstThread);
- lwp_suspend(*LWP_Thread::firstThread);
- }
- #endif
-
- p1->Body();
- }
-
- void LWP_Thread::Suspend ()
- {
- #ifdef __GNUG__
- if ((LWP_Thread::firstThread != 0) && (!done))
- {
- done = true;
- lwp_resume(*LWP_Thread::firstThread);
- }
- #endif
-
- (void) lwp_suspend(mid);
- }
-
- void LWP_Thread::Resume ()
- {
- #ifdef __GNUG__
- if ((LWP_Thread::firstThread != 0) && (done))
- #endif
- (void) lwp_resume(mid);
- }
-
- void LWP_Thread::Sleep (struct timeval doze) { (void) lwp_sleep(doze); }
-
- thread_t LWP_Thread::Thread_ID () const { return mid; }
-
-
-
- //
- // Getting the main thread into the thread list...
- //
-
- class LWP_Main_Thread : public LWP_Thread
- {
- public:
- LWP_Main_Thread (thread_t t) : LWP_Thread(t) {}
- ~LWP_Main_Thread ();
-
- void Body ();
- };
-
- LWP_Main_Thread::~LWP_Main_Thread () {}
-
- void LWP_Main_Thread::Body () {}
-
- void LWP_Thread::Initialize ()
- {
- (void) pod_setmaxpri(MaxPriority);
- (void) lwp_setstkcache(4000, 40);
-
- thread_t me;
- lwp_self(&me);
- new LWP_Main_Thread(me);
- }
- lwp_create are as a result
- * of the way in which C++ allows C routines to be declared and the way in which
- * Sun's lwp_create is defined.
- */
-
- extern "C"
- {
- #incC++SIM/lwp_thread.h
- * Copyright (C) 1993
- *
- * Department of Computing Science,
- * The University,
- * Newcastle upon Tyne,
- * UK.
- */
-
- #ifndef LWP_THREAD_H_
- #define LWP_THREAD_H_
-
- #include <lwp/lwp.h>
-
- #ifndef THREAD_H_
- #include "thread.h"
- #endif
-
- /* This is the Sun thread implementation of the Thread virtual class. It provides
- * an implementation for all of the pure virtual functions declared in the Thread
- * base class.
- * The Initialize function must be called at the start of any program which uses the
- * threads implementation as it calls necessary Sun thread initialization routines.
- *
- * Note: if any problems occur when using the Sun thread package, try increasing the
- * stack size and/or the number of stacks to create in Initialize.
- */
-
-
- class LWP_Thread : public Thread
- {
- public:
- virtual void Suspend (); // Suspend an active thread
- virtual void Resume (); // Resume a suspended thread
- virtual void Sleep (struct timeval); // Put active thread to sleep for duration specified
-
- virtual void Body () = 0; // Body of "active" object (defined in the deriving class)
- virtual long Current_Thread () const; // Returns current thread id
-
- thread_t Thread_ID () const; // Returns current thread's Sun thread_key
-
- // Initialize must be called exactly once at the start of the program
- static void Initialize ();
-
- protected:
- static const int MaxPriority; // Maximum priority of a thread
-
- LWP_Thread (int priority = MaxPriority); // Create thread with given (or maximum) priority
- LWP_Thread (thread_t); // Create thread with given Sun thread_key
- virtual ~LWP_Thread ();
-
- private:
- static void Execute (LWP_Thread*); // This routine calls the 'main' object code
-
- #ifdef __GNUG__
- static thread_t* firstThread;
- static boolean done;
- #endif
-
- thread_t mid;
- };
-
- #endif
- spend(*LWP_Thread::firstThread);
- }
- #endif
-
- p1->Body();
- }
-
- void LWP_Thread::Suspend ()
- {
- #ifdef __GNUG__
- if ((LWP_Thread::firsC++SIM/thread.cc
- * Copyright (C) 1993
- *
- * Department of Computing Science,
- * The University,
- * Newcastle upon Tyne,
- * UK.
- */
-
- #ifndef THREAD_H_
- #include "thread.h"
- #endif
-
-
- class Thread *Thread::head = 0; // Initialise head of Thread list
-
-
- Thread::Thread ()
- {
- Thread *marker = head;
-
- if (head != 0)
- {
- while (marker->next != 0)
- marker = marker->next;
-
- marker->next = this;
- marker->next->prev = marker;
- marker = marker->next;
- marker->next = 0;
- }
- else
- {
- this->prev = 0;
- this->next = 0;
- head = this;
- }
-
- thread_key = 0;
- // Actual thread key value MUST be set in derived class constructor
- }
-
- Thread::~Thread ()
- {
- if (this->prev != 0)
- this->prev->next = this->next;
- else
- head = this->next;
- }
-
- long Thread::Identity () const { return thread_key; }
-
- Thread *Thread::Self ()
- {
- if (!head) return 0;
-
- // Use any thread object (e.g., head) to get access to the current thread
- long my_id = head->Current_Thread();
-
- for (Thread *marker = head; marker; marker=marker->next)
- if (marker->thread_key == my_id)
- break;
-
- return marker;
- }
- ct (defined in the deriving class)
- virtual long Current_Thread () const; // Returns current thread id
-
- thread_t Thread_ID () const; // Returns current thread's Sun thread_key
-
- // Initialize must be called exactly once at the start of the program
- static void Initialize ();
-
- protected:
- static const int MaxPriority; // Maximum priority of a thread
-
- LWP_Thread (int priority = MaxPriority); // CrC++SIM/thread.h
- * Copyright (C) 1993
- *
- * Department of Computing Science,
- * The University,
- * Newcastle upon Tyne,
- * UK.
- */
-
- #ifndef THREAD_H_
- #define THREAD_H_
-
- /* This class defines a template for threads packages which will be used to
- * provide "active" objects in C++. Such objects are not derived from this
- * class, but instead a thread implementation class is derived from this.
- * That class will then define the pure virtual functions, and "active" objects
- * are then derived from that class.
- * Because not every thread package provides an easy way of identifying and locating
- * threads, the Thread class does provide such a scheme through the use of the
- * Identify and Self operations. A linked list of threads is formed and added to
- * whenever a new thread is created.
- */
-
- class Thread
- {
- public:
- virtual void Suspend () = 0; // How to suspend a thread
- virtual void Resume () = 0; // How to resume a suspended thread
- virtual void Body () = 0; // The 'main' part of the code
-
- virtual long Current_Thread () const = 0; // Should return some unique thread identity key
-
- virtual long Identity () const; // Returns the identify of this thread
- static Thread *Self (); // Returns the current thread
-
- protected:
- Thread ();
- virtual ~Thread ();
-
- long thread_key;
-
- private:
- Thread *next, *prev;
- static Thread *head;
- };
-
- #endif
- tatic void Initialize ();
-
- protected:
- static const int MaxPriority; // Maximum priority of a thread
-
- LWP_Thread (int priority = MaxPriority); // CrC++SIM/Process.n
- * Copyright (C) 1993
- *
- * Department of Computing Science,
- * The University,
- * Newcastle upon Tyne,
- * UK.
- */
-
-
- #if defined(NO_INLINES) && !defined(PROCESS_CC_)
-
- #else
-
- #ifndef NO_INLINES
- # define INLINEF inline
- #else
- # define INLINEF
- #endif
-
-
- INLINEF void Process::set_evtime (double time)
- {
- wakeuptime = time;
- }
-
- INLINEF void Process::Activate ()
- {
- ReActivate();
- }
-
- INLINEF double Process::evtime () const
- {
- return wakeuptime;
- }
-
- INLINEF boolean Process::terminated () const
- {
- return Terminated;
- }
-
-
- #ifdef INLINEF
- # undef INLINEF
- #endif
-
- #endif
- * The University,
- * Newcastle upon Tyne,
- * UK.
- */
-
-
- #if defined(NO_INLINES) && !defined(PROCESS_CC_)
-
- #else
-
- #ifndef NO_INLINES
- # define INLINEF inline
- #else
- # define INLINEF
- #endif
-
-
- INLINEF void Process::set_evtime (double time)
- {
- wakeuptime = time;
- }
-
- INLINEF void Process::Activate ()
- {
- ReActivate();
- }
-
- INLINEF double Process::evtime () const
- {
- return wakeuptime;
- }
-
- INLINEF boolean Process::terminated () const
- {
- returnC++SIM/Process.cc
- * Copyright (C) 1993
- *
- * Department of Computing Science,
- * The University,
- * Newcastle upon Tyne,
- * UK.
- */
-
- #include <iostream.h>
- #include <stdlib.h>
-
- #ifndef COMMON_H_
- #include "common.h"
- #endif
-
- #ifndef PROCESS_H_
- #include "Process.h"
- #endif
-
- #ifndef PROCESSITERATOR_H_
- #include "ProcessIterator.h"
- #endif
-
- #ifndef PROCESSLIST_H_
- #include "ProcessList.h"
- #endif
-
- #ifndef PROCESSCONS_H_
- #include "ProcessCons.h"
- #endif
-
- static ProcessList ReadyQueue;
- static Process *Current = 0;
-
- //
- // create scheduler task at MINPRIO
- //
-
- Scheduler::Scheduler () : Thread_Type(MINPRIO) {}
-
- Scheduler::~Scheduler () {}
-
- void Scheduler::Body ()
- {
- for (;;)
- {
- Current = ReadyQueue.Remove();
- if (Current == 0) // all done
- {
- #ifdef DEBUG
- cerr << "Scheduler queue is empty.\n";
- #endif
- exit(0);
- }
-
- if (Current->evtime() < 0)
- cerr << "Scheduler Error: Process WakeupTime Invalid.\n";
- else
- SimulatedTime = Current->evtime();
-
- #ifdef DEBUG
- cerr << "Simulated time is now " << SimulatedTime << "\n";
- #endif
-
- Current->Resume();
- }
- }
-
- double Scheduler::CurrentTime () const { return SimulatedTime; }
-
-
- //
- // Class Process
- //
-
- const int Process::Never=-1; // Process will never awaken.
-
- Process::~Process () {}
-
- double Process::CurrentTime () { return SimulatedTime; }
-
-
- double Process::Time () const { return SimulatedTime; }
-
- void Process::ActivateBefore (Process &p)
- {
- // No op if already scheduled
- if (idle()) return;
-
- if (ReadyQueue.InsertBefore(*this, p))
- wakeuptime = p.wakeuptime;
- else
- cerr << "ActivateBefore failed because 'before' process is not scheduled" << endl;
- }
-
- void Process::ActivateAfter (Process &p)
- {
- // No op if already scheduled
- if (idle()) return;
-
- if (ReadyQueue.InsertAfter(*this, p))
- wakeuptime = p.wakeuptime;
- else
- cerr << "ActivateAfter failed because 'after' process is not scheduled" << endl;
- }
-
- void Process::ActivateAt (double AtTime, boolean prior)
- {
- // No op if already scheduled
- if (idle()) return;
-
- wakeuptime = AtTime;
- ReadyQueue.Insert(*this, prior);
- }
-
- void Process::ActivateDelay (double Delay, boolean prior)
- {
- // No op if already scheduled
- if (idle()) return;
-
- wakeuptime = SimulatedTime + Delay;
- ReadyQueue.Insert(*this, prior);
- }
-
-
- // Similarly, there are four ways to reactivate
- // Note that if a process is already scheduled, the reactivate
- // will simply re-schedule the process.
-
- void Process::ReActivateBefore (Process &p)
- {
- Cancel();
- ActivateBefore(p);
- }
-
- void Process::ReActivateAfter (Process &p)
- {
- Cancel();
- ActivateAfter(p);
- }
-
- void Process::ReActivateAt (double AtTime, boolean prior)
- {
- Cancel();
- ActivateAt(AtTime, prior);
- }
-
- void Process::ReActivateDelay (double Delay, boolean prior)
- {
- Cancel();
- ActivateDelay(Delay, prior);
- }
-
- void Process::ReActivate ()
- {
- if (idle())
- ReadyQueue.Remove(this);
- set_evtime(CurrentTime());
- Resume();
- }
-
- // cancels next burst of activity, process becomes idle
- void Process::Cancel ()
- {
- if (idle())
- ReadyQueue.Remove(this);
- else
- Suspend();
-
- wakeuptime = Process::Never;
- }
-
- boolean Process::idle ()
- {
- if (wakeuptime == CurrentTime())
- return false;
- else
- return true;
- }
-
- Process::Process() : Thread_Type()
- {
- wakeuptime = CurrentTime();
- }
-
- // suspend current process for simulated time t
- void Process::Hold (double t)
- {
- ActivateDelay(t);
- Suspend();
- }
-
- // suspend current process indefinitely (i.e., make idle)
- void Process::Passivate ()
- {
- wakeuptime = Process::Never;
- this->Terminated = true;
- Suspend();
- }
-
-
- #ifdef NO_INLINES
- # define PROCESS_CC_
- # include "Process.n"
- # undef PROCESS_CC_
- #endif
- private:
- double Mean,StandardDeviation;
- double p;
- };
-
- class NormalStream : public RandomStream
- {
- public:
- NormalStream (double Mean, double StandardDeviation, int StreamSelect=0);
- virtual double operator() ();
-
- private:
- double Mean,StandardDeviation;
- double z;
- };
-
- #endif // RANDOM_H
-
- lgorithms, Knuth, Addison-Wesley, p.117
-
- double X2;
-
- if (z!=0.0) {
- X2 = z;
- z = 0.0;
- } else {
- double SC++SIM/Version
- * Copyright (C) 1993
- *
- * Department of Computing Science,
- * The University,
- * Newcastle upon Tyne,
- * UK.
- */
-
- This is version 1.1 of C++SIM. The only changes from 1.0 are bug fixes in
- the code and enhancements to allow it to work with g++ and Sun's lwp
- package at the same time (up until now if you wanted to use g++ you had to
- use their threads package too).
-
- Mark Little 16/7/93.
- CONS_H_
- #include "ProcessCons.h"
- #endif
-
- static ProcessList ReadyQueue;
- static Process *Current = 0;
-
- //
- // create schedu
- * Copyright (C) 1993
- *
- * Department of Computing Science,
- * The University,
- * Newcastle upon Tyne,
- * UK.
- */
-
-
- #if defined(NO_INLINES) && !defined(PROCESS_CC_)
-
- #else
-
- #ifndef NO_INLINES
- # define INLINEF inline
- #else
- # define INLINEF
- #endif
-
-
- INLINEF void Process::set_evtime (double time)
- {
- wakeuptime = time;
- }
-
- INLINEF void Process::Activate ()
- {
- ReActivate();
- }
-
- INLINEF double Process::evtime () const
- {
- return wakeuptime;
- }
-
- INLINEF boolean Process::terminated () const
- {
- return
- }
-